package com.example.ormsqlsplicingframe1.warpper;

import com.example.ormsqlsplicingframe1.note.JoinDate;
import com.example.ormsqlsplicingframe1.note.JoinDateEnum;
import com.example.ormsqlsplicingframe1.note.JoinFieldMajorKey;
import com.example.ormsqlsplicingframe1.orm.Util.StringUtil;

import com.example.ormsqlsplicingframe1.orm.note.AddBatch;
import com.example.ormsqlsplicingframe1.orm.note.Title;
import com.example.ormsqlsplicingframe1.session.NodeSql;
import com.example.ormsqlsplicingframe1.session.SessionUtil;
import com.example.ormsqlsplicingframe1.sql.impl.InsertImpl;
import com.example.ormsqlsplicingframe1.utlis.GetDate;
import com.example.ormsqlsplicingframe1.utlis.GetGenerics;
import com.example.ormsqlsplicingframe1.utlis.NodeSqlUtil;
import com.example.ormsqlsplicingframe1.utlis.ObjValue;
import lombok.SneakyThrows;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class InsertSqlWrapper {

   private InsertImpl insert = new InsertImpl();


    private Object object;


    private boolean isLog = true;

    private boolean isAddBatch = false;


    public int  execute(){

        if(isAddBatch){
            return SessionUtil.getSession().insert(isLog);
        }else {
            return SessionUtil.getSession().insert(insert);
        }
    }

    @SneakyThrows
    private void wrapper(){


        Class<?> aClass = object.getClass();
        NodeSql sql = new NodeSql();
        if (aClass.getAnnotation(Title.class) == null){
            throw new RuntimeException("当前对象没有：Title 注解");
        }
        Title title = aClass.getAnnotation(Title.class);
        insert.table(title.titleName());

        if (aClass.getAnnotation(AddBatch.class) != null) NodeSqlUtil.addBatch();

        for (Field field : aClass.getDeclaredFields()) {
            field.setAccessible(true);

            JoinFieldMajorKey annotation = field.getAnnotation(JoinFieldMajorKey.class);
            String name = StringUtil.javaTurnSql(field.getName());
            Object value = field.get(object);
            if (annotation != null){

                Object o = field.get(object);
                if (o != null){
                    value = o;
                }else {
                    value = returnValue(field);
                }

                field.set(object,value);
            }

            //时间添加类型
            JoinDate date = field.getAnnotation(JoinDate.class);
            if (date != null){

                if (date.value() == JoinDateEnum.INSERT_TIME){
                    value = GetDate.date();
                }else {
                    value = GetDate.date();
                }
                field.set(object,GetDate.date(value));
            }

            if (field.getType() == List.class){
                value = GetGenerics.listChangeSingle(value);
            }

            if (ObjValue.isNotNull(value)){
                insert.field(name,value);
                if (isAddBatch){
                    sql.setList(value);
                }
            }
        }
        if (isAddBatch){
            sql.setInsert(insert);
            NodeSqlUtil.add(sql);

        }
    }


    //返回当前对象主键值
    private Object returnValue(Field field){

        Date date = new Date();

        if (field.getType() == Integer.class){

            Long time = date.getTime();
            return time.intValue();
        }

        if (field.getType() == Long.class){
            return date.getTime();
        }

        if (field.getType() == String.class){
            return GetDate.date(date);
        }

        return null;
    }

    public InsertSqlWrapper() {
    }

    public InsertSqlWrapper print(){
        this.isLog = false;
        return this;
    }

    public InsertSqlWrapper(Object object) {

        if (object instanceof List){
            this.isAddBatch = true;
            ((List<Object>) object).forEach(row ->{
                this.object = row;
                wrapper();
            });
        }else {
            this.object = object;
            wrapper();
        }



    }

    private static InsertSqlWrapper insertSqlWrapper = null;

    public synchronized static InsertSqlWrapper newInstance(Object object){

        if (insertSqlWrapper == null) {
            return new InsertSqlWrapper(object);
        }
        return insertSqlWrapper;
    }


}
